import 'dart:typed_data';

import 'package:bluetooth_protocols_plugin/library.dart';

import '../../../tools/bit_utils.dart';
import '../../../tools/utils.dart';

// v12s 实时电池信息
class V12sRealtimeBatteryInfo
    extends LorinRealtimeBatteryInfo<V12sBatteryPackInfo> {
  // 电池组信息
  final List<V12sBatteryPackInfo> _batteryPacks = [];

  V12sRealtimeBatteryInfo.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
    if (bytes.length < minLength) {
      throw ArgumentError('Bytes length is less than minimum length.');
    }

    final singleLen = minLength ~/ 2; // 每个电池包的长度
    for (int i = 0; i < batteryPacksCount; i++) {
      final offset = i * singleLen;
      final packBytes = bytes.sublist(offset, offset + singleLen);
      _batteryPacks.add(V12sBatteryPackInfo.fromBytes(packBytes));
    }
  }

  @override
  List<V12sBatteryPackInfo> get batteryPacks => _batteryPacks;

  @override
  int dataIntValue() =>
      _batteryPacks.fold(0, (total, pack) => total + pack.dataIntValue());

  @override
  int dataLength() =>
      _batteryPacks.fold(0, (total, pack) => total + pack.dataLength());

  @override
  Uint8List toBytes() {
    final result = Uint8List(dataLength());
    int offset = 0;

    for (final pack in _batteryPacks) {
      final packBytes = pack.toBytes();
      result.setRange(offset, offset + packBytes.length, packBytes);
      offset += packBytes.length;
    }

    return result;
  }

  @override
  Map<String, dynamic> toMap() {
    return {
      'version': '$runtimeType',
      'batteryPacks': _batteryPacks.map((pack) => pack.toMap()).toList(),
      'dataLength': dataLength(),
      'minLength': minLength,
      'bytes': Utils.uint8List2HexString(toBytes()),
    };
  }
}

// v12s 电池组信息
class V12sBatteryPackInfo extends LorinBatteryPackInfoBase {
  int chargeCurrent = 0; // 充电电流 单位 0.1A
  int dischargeCurrent = 0; // 放电电流 单位 0.1A
  bool errorCannotCharge = false; // 不能充电错误
  bool batteryWarning = false; // 电池警告
  bool batteryProtection = false; // 电池保护
  bool batteryError = false;

  V12sBatteryPackInfo.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
    int offset = 0;
    var byteData = ByteData.sublistView(bytes);
    voltage = byteData.getUint16(offset, Endian.big);
    chargeCurrent = byteData.getInt16(offset + 2, Endian.big);
    dischargeCurrent = byteData.getInt16(offset + 4, Endian.big);

    int stateBits = byteData.getUint16(offset + 6, Endian.big);
    stateDetected = BitUtils.isBitOne(stateBits, 0);
    stateEnable = BitUtils.isBitOne(stateBits, 1);
    stateCharge = BitUtils.isBitOne(stateBits, 2);
    // state_reserve        : 3; //保留
    errorLogic = BitUtils.isBitOne(stateBits, 6);
    errorSignal = BitUtils.isBitOne(stateBits, 7);
    errorVoltageSensor = BitUtils.isBitOne(stateBits, 8);
    errorCurrentSensor = BitUtils.isBitOne(stateBits, 9);
    errorCannotCharge = BitUtils.isBitOne(stateBits, 10);
    batteryWarning = BitUtils.isBitOne(stateBits, 11);
    batteryProtection = BitUtils.isBitOne(stateBits, 12);
    batteryError = BitUtils.isBitOne(stateBits, 13);
  }

  @override
  Map<String, dynamic> toMap() {
    var map = super.toMap(); // 先获取父类的 Map
    map['version'] = 'V12sBatteryPackInfo';
    map['chargeCurrent'] = chargeCurrent;
    map['dischargeCurrent'] = dischargeCurrent;
    map['errorCannotCharge'] = errorCannotCharge;
    map['batteryWarning'] = batteryWarning;
    map['batteryProtection'] = batteryProtection;
    map['batteryError'] = batteryError;
    return map;
  }

  @override
  Uint8List toBytes() {
    var byteData = ByteData(bytesLength);

    // 实时数据
    byteData.setUint16(0, voltage, Endian.big);
    byteData.setInt16(2, chargeCurrent, Endian.big);
    byteData.setInt16(4, dischargeCurrent, Endian.big);

    // 状态位
    int stateBits = 0;
    stateBits |= BitUtils.setBit(0, stateDetected);
    stateBits |= BitUtils.setBit(1, stateEnable);
    stateBits |= BitUtils.setBit(2, stateCharge);
    // 故障或警告位
    stateBits |= BitUtils.setBit(6, errorLogic);
    stateBits |= BitUtils.setBit(7, errorSignal);
    stateBits |= BitUtils.setBit(8, errorVoltageSensor);
    stateBits |= BitUtils.setBit(9, errorCurrentSensor);
    stateBits |= BitUtils.setBit(10, errorCannotCharge);
    stateBits |= BitUtils.setBit(11, batteryWarning);
    stateBits |= BitUtils.setBit(12, batteryProtection);
    stateBits |= BitUtils.setBit(13, batteryError);

    byteData.setUint16(6, stateBits, Endian.big);

    return byteData.buffer.asUint8List();
  }

  @override
  int get bytesLength => 8;

  @override
  int dataIntValue() {
    return voltage +
        chargeCurrent +
        dischargeCurrent +
        (stateDetected ? 1 : 0) +
        (stateEnable ? 1 : 0) +
        (stateCharge ? 1 : 0) +
        (errorLogic ? 1 : 0) +
        (errorSignal ? 1 : 0) +
        (errorVoltageSensor ? 1 : 0) +
        (errorCurrentSensor ? 1 : 0) +
        (errorCannotCharge ? 1 : 0) +
        (batteryWarning ? 1 : 0) +
        (batteryProtection ? 1 : 0) +
        (batteryError ? 1 : 0);
  }

  @override
  int dataLength() {
    return bytesLength;
  }
}
